/**
 * @author David Young
 */
package csab.core;

import java.awt.Rectangle;

/**
 * This class is meant to provide standard collision functionality to
 * derived classes. Abstract and must be over-ridden.
 * @author David Young
 */
public abstract class Collidable extends Entity {
	protected Rectangle boundingbox;
	private boolean canCollide;
	private boolean isBased;
	
	/**
	 * Constructor for an object of this class.
	 * @param name The name which will be assigned to
	 * this Entity. Does not have to be unique.
	 * @see csab.core.Entity
	 */
	public Collidable(String name) {
		super(name);
		canCollide = true;
		isBased = false;
		boundingbox = new Rectangle();
	}
	
	/**
	 * Determines if this object is meant to collide with other objects.
	 * @return true if this object is meant to collide with others.
	 */
	public boolean canCollide() {
		return canCollide;
	}
	
	/**
	 * Check to see if this object's boundingbox intersects, contains, or
	 * is contained by cbox.
	 * @param cbox The Rectangle to check for collisions against.
	 * @return true if cbox collides with this object's boundingbox.
	 * @see java.awt.Rectangle
	 */
	public boolean collides(Rectangle cbox)
	{
		Rectangle tbox = this.getCollisionBox();
		return (cbox.contains(tbox) ||
				tbox.contains(cbox) || 
				tbox.intersects(cbox));
	}
	/**
	 * Check to see if this Collidable object intersects, contains,
	 * or is contained by item.
	 * @param item The object to check for collision against.
	 * @return true if this object collides with item.
	 */
	public boolean collides(Collidable item)
	{
		Rectangle cbox = item.getCollisionBox();
		return this.canCollide && item.canCollide && collides(cbox);
			   
	}
	
	/** 
	 * Collision operation to perform when a collision occurs.
	 * @param obj The object that this object collides with.
	 */
	public abstract void doCollide(Collidable obj);
	
	/**
	 * Get the collision box of this object.
	 * @return A mutable reference to this object's bounding box.
	 * @see java.awt.Rectangle
	 */
	public final Rectangle getCollisionBox()
	{
		return boundingbox;
	}
	
	/**
	 * Return whether or not this object is based on something.
	 * @return Whether or not this object is based atop a 
	 * Collidable object.
	 */
	public boolean isBased() {
		return isBased;
	}
	/**
	 * Set whether or not this Entity is based on top
	 * of a Collidable terrain piece.
	 * @param isBased the isBased to set
	 */
	public void setBased(boolean isBased) {
		this.isBased = isBased;
	}
	
	/**
	 * Dictate whether or not his object has the ability to collide with
	 * other Collidable objects.
	 * @param canCollide Whether or not this object can collide with others.
	 */
	public void setCanCollide(boolean canCollide) {
		this.canCollide = canCollide;
	}

	
	/**
	 * Set the height of both this Entity's collision box
	 * and its drawing height.
	 * @param height The new height of this Entity's drawing
	 * height and its collision box.
	 */
	public void setHeight(int height)
	{
		boundingbox.height = height;
		super.setHeight(height);
	}
	
	/**
	 * Sets the objects new position in the world space.
	 * @param x The new x-axis position of this object.
	 * @param y The new y-axis position of this object.
	 */
	public void setPos(float x, float y)
	{
		boundingbox.x = (int)x;
		boundingbox.y = (int)y;
		super.setPos(x, y);
	}

	/**
	 * Set the width of both this Entity's collision box
	 * and its drawing width.
	 * @param width The new width of this Entity's drawing
	 * width and its collision box.
	 */
	public void setWidth(int width)
	{
		boundingbox.width = width;
		super.setWidth(width);
	}

	/**
	 * The new x-axis position of this object. By default, this 
	 * sets the x-axis position of both the drawing image and the
	 * bounding box.
	 * @param x A floating point value representing this object's 
	 * new x axis position. 
	 */
	public void setX(float x) {
		boundingbox.x = (int)x;
		super.setX(x);
	}
	
	/**
	 * The new y-axis position of this object. By default, this 
	 * sets the y-axis position of both the drawing image and the
	 * bounding box.
	 * @param y A floating point value representing this object's 
	 * new y axis position.
	 */
	public void setY(float y) {
		boundingbox.y = (int)y;
		super.setY(y);
	}

	/* (non-Javadoc)
	 * @see csab.core.Entity#doDestroy()
	 */
	@Override
	public void doDestroy() {
		this.setCanCollide(false);
		super.doDestroy();
	}
}
